
/**
	*	@file findrec.c
	*	@brief Programa responsável por pesquisa no arquivo de dados, dado um número de registros passado por parâmetro.
	*   @author  Daniel Bittencourt
	*   @version 15
	*
	*   Este programa faz a pesquisa no arquivo de dados binário tendo como entrada um número de um registros pesquisado.
	*   Ao achar o registro este imprime na tela as informações desejadas assim como o número de blocos consultados e o número
	*   de blocos total do arquivo.
	*
	*	@sa BD1.h
	*   @sa upload.c
	*
	**/

#include "BD1.h"

/**
*   @fn int funcHash1(int CODIGO)
*   @brief Função de hash que retorna o valor aonde será procurado o regitro referente ao número informado.
*   @param CODIGO Codigo lido da linha do arquivo base já convertida para inteiro.
*   @return retorna o bucket que poderá conter o registro procurado.
*   @sa @file upload.c @fn int funcHash1(int CODIGO)
*/
int funcHash1(int CODIGO){
    return (CODIGO % num_buckets);
}

/**
*   @fn tipoDado leTupla(char* linha, tipoDado *registro)
*   @brief Funcao que recebe os dados lidos do arquivo de dados caso o registro referente ao código passado seja achado.
*   @return retorna o registro com os campos preenchidos pelas informações da linha lida.
*/

tipoDado alocaDados(){
    tipoDado temp;

    temp.CODIGO = (char *) malloc (sizeof(char) * 8);
    temp.NOME = (char *) malloc (sizeof(char) * 50);
    temp.DATA_NASC = (char *) malloc (sizeof(char) * 10);
    temp.LOCAL = (char *) malloc (sizeof(char) * 32);

    return temp;
}

/**
*   @fn int procuraReg (tipoBucket *tempBucket,int chave, tipoDado *registro)
*   @brief Funcao que procura uma chave em um Bucket e se achado, retorna os dados em uma variável tipoDado para posterior impressão.
*   @param tempBucket Bucket lido do arquivo de dados
*   @param chave Variável que receberá o código passado como argumento para o prog para pesquisa do registro.
*   @param registro Ponteiro para o registro temporário que recebera as informações do registro procurado, lido da base de dados
*   @return Retorna -1 se o registro não for localizado ou a quantidade de blocos lidos até achar o registro
*/

int procuraReg (tipoBucket *tempBucket,int chave, tipoDado *registro){
    int contBlk,contReg,tempCODIGO;

    for (contBlk=0;contBlk<blks_bucket;contBlk++){
        for(contReg=0;contReg<reg_blk;contReg++){

            tempCODIGO = atoi(tempBucket->blocos[contBlk].registros[contReg].CODIGO);

            //printf("\nCodigo Sendo Lido do Bucket: %d, chave %d\n",tempCODIGO,chave);
            if (chave == tempCODIGO){
                strcpy(registro->CODIGO,tempBucket->blocos[contBlk].registros[contReg].CODIGO);
                registro->CODIGO[8] = '\0';
                strcpy(registro->NOME,tempBucket->blocos[contBlk].registros[contReg].NOME);
                registro->NOME[60] = '\0';
                strcpy(registro->DATA_NASC,tempBucket->blocos[contBlk].registros[contReg].DATA_NASC);
                registro->DATA_NASC[10] = '\0';
                strcpy(registro->LOCAL,tempBucket->blocos[contBlk].registros[contReg].LOCAL);
                registro->LOCAL[32] = '\0';

                //Mais 1 pois a contagem começa no zero
                return contBlk + 1;
            }
        }
    }
    return -1;
}

/**
*   @fn int main(int argc,char **argv)
*   @brief Main do programa.
*   Recebe como argumento a chave a ser pesquisada. Esta chave é jogada na função hash que devolve o bucket onde a chave pode estar.
*   De posse do número do Bucket este é carregado para uma variável temporária e passado para a funcao procuraReg que faz a busca no bucket.
*   @param argc Conta a quantidade de parâmetros passados para o programa.
*   @param argv Recebe as strings das informações passadas como parâmetro para o programa
*   @sa @fn tipoDado alocaDados()
*   @sa @fn int funcHash1(int CODIGO)
*   @sa @fn int procuraReg (tipoBucket *tempBucket,int chave, tipoDado *registro)
*/

int main(int argc,char **argv){

	tipoBucket bucketTemp;
	tipoDado regTemp;
	int resultHash,blkProcurados,totalBlks,codigoTemp;
    FILE *arqDados;

    //printf("The page size for this system is %ld bytes\n", sysconf(_SC_PAGE_SIZE)); //_SC_PAGE_SIZE is OK too.


    //Verifica se o arquivo TXT eh passado como parametro
	if( argc < 2 ){
		printf("\nModo de usar:\n     %s [codigo]\n\n", argv[0] );
		return 1;
	}


    if (( arqDados = fopen("arqDados.bin", "rb") ) == NULL ){
			printf( "\nErro na abertura do arquivo de dados\n");
			return 1;
    }

    regTemp = alocaDados();

    codigoTemp = atoi(argv[1]);

    printf("Codigo lido como parametro: %d", codigoTemp);

    resultHash = funcHash1(codigoTemp);

    fseek(arqDados, resultHash * sizeof(tipoBucket), SEEK_SET);
    fread(&bucketTemp, sizeof(tipoBucket), 1, arqDados);

    fseek(arqDados,0,SEEK_END);
    totalBlks = ftell(arqDados)/sizeof(tipoBucket) * blks_bucket;

    blkProcurados = procuraReg (&bucketTemp,codigoTemp, &regTemp);

    if(blkProcurados > 0){
        printf("Registro encontrado!\n");
        printf("Registro: \n Nome: %s\n Data_nasc: %s\n Local: %s\n",regTemp.NOME,regTemp.DATA_NASC,regTemp.LOCAL);
        printf("Foi nescessária a leitura de %d blocos de %d presentes no arq. de dados\n",blkProcurados,totalBlks);
    }
    else
        printf("Codigo nao encontrado\n");

return 0;

}
